<template>
    <div class="editor-wrapper">
        <div ref="editorContainer" class="editor-container"></div>
    </div>
</template>

<script setup>
import { onMounted, onBeforeUnmount, ref, watch, computed } from 'vue'
import { EditorView, basicSetup } from 'codemirror'
import { javascript } from '@codemirror/lang-javascript'
import { css } from '@codemirror/lang-css'
import { placeholder } from '@codemirror/view'

const props = defineProps({
    modelValue: String,
    placeholder: String,
    lang: {
        type: String,
        default: 'js' // 可选值：'js' | 'css'
    }
})
const emit = defineEmits(['update:modelValue'])

const editorContainer = ref(null)
let editorView = null

// 根据语言返回语言扩展
const getLangExtension = () => {
    if (props.lang === 'css') return css()
    return javascript()
}

onMounted(() => {
    editorView = new EditorView({
        doc: props.modelValue || '',
        extensions: [
            basicSetup,
            getLangExtension(),
            placeholder(props.placeholder || ''),
            EditorView.updateListener.of((v) => {
                if (v.docChanged) {
                    emit('update:modelValue', v.state.doc.toString())
                }
            })
        ],
        parent: editorContainer.value
    })
})

// 外部 v-model 同步内容变化
watch(() => props.modelValue, (newVal) => {
    if (!editorView) return
    const current = editorView.state.doc.toString()
    if (newVal !== current) {
        editorView.dispatch({
            changes: { from: 0, to: current.length, insert: newVal || '' }
        })
    }
})

// 如果语言类型变了，重新加载语言扩展
watch(() => props.lang, (newLang) => {
    if (!editorView) return
    editorView.dispatch({
        effects: EditorView.reconfigure.of([
            basicSetup,
            getLangExtension(),
            placeholder(props.placeholder || ''),
            EditorView.updateListener.of((v) => {
                if (v.docChanged) {
                    emit('update:modelValue', v.state.doc.toString())
                }
            })
        ])
    })
})

onBeforeUnmount(() => {
    if (editorView) editorView.destroy()
})
</script>

<style scoped>
.editor-wrapper {
    height: 100%;
    width: 100%;
    display: flex;
    flex-direction: column;
}

.editor-container {
    flex: 1;
    width: 100%;
    height: 100%;
    overflow: auto;
}
</style>